DOCUMENT SP0001 Begun: 3 July 2001 Most Recent Edit: 2003 / 07 / 21 THE HUMANE ENVIRONMENT (THE) EXTERNAL TECHNICAL SPECIFICATION Document SP0001 V0069 ©1986 - 2003 AUTHORS AND EDITORS This document began as the specifications for the Swyft portable computer, version 33, 9 July 1986, by Jef Raskin. Many have contributed directly to this newer specification and its forbears, notably Paul Baker, Jim Straus, David Alzofon, Rebecca Fureigh, Ian Patterson, Aza Raskin, Richard Karpinski, Andrew Greenberg, Douglas McKenna, Astrid Raffinpeyloz, Scott Kim, Hanhwe Kim, Neil Stockbridge, Galen Panger, Rich Morin, Trenton Henry, Matt Wilkie, Dan Strychalski, Jean Bergstrom, John Bear, Brad Lauster, Ryan Brown, and Jef Raskin. REVISION HISTORY NOTE ON V 69 The method of invoking LEAP as in V 68 depends on using the Command key (Mac, Linux) or the Window key (Win) to establish the command quasimode. This change did not get into V 68, but has been corrected here. NOTE ON V 68 Included in this revision is a change to the method of invoking LEAP on a standard keyboard. The change makes LEAP (a) faster to invoke, (b) lowers the typing error rate, and (c) is usable on the keyboards of nearly all countries that use phonetic alphabets. Also, a Revision History has been added. NOTE ON V 67 Included in this revision are very extensive edits and corrections by David Alzofon, and a few by Jef Raskin. No major substantive changes to the spec were made, but the nomenclature is considerably cleaner and more uniform and some ambiguities have been clarified. The English has been betterfied. DOCUMENT MAINTENANCE Jef Raskin PROJECT SCOPE For an overall definition of The Humane Environment (abbreviated THE), see "So The Humane Environment isn't an editor, what is it?" on www.jefraskin.com. This portion of the specification details the low-level interactions that take place primarily within a document. A master document can be thought of as an unending piece of paper on which text and images are placed. The "low-level" interactions cover everything from entering your name in a game to writing novels. For the most part, these low-level interactions are those parts of the interface that can also be used by the visually impaired. THE -- even if limited to that part described here -- is a practical writing and programming tool. It demonstrates LEAP(tm) and some of the selection and command interface techniques described in "The Humane Interface" [Raskin, 2000]. The Humane Environment (THE) is intended to run on at least Windows, Linux, and Mac platforms. A separate specification will discuss the zooming user interface portion of THE. NATURAL LANGUAGE QUOTING CONVENTIONS Literals inside quotes are exact. For example, a sentence that ends with a quote, He said, "Hello, George.". would appear as shown. The first period ends the sentence inside the quote. The second period ends the overall sentence itself. This is not conventional punctuation, but it is a rule we need in order to avoid ambiguity. A more pertinent example is, To stop the movie, type "stop.". which has only one interpretation. It is clear that a period is part of the command. If we wrote, using the conventional but illogical rule, To stop the movie, type "stop." it would be unclear of just what characters the command consists. Compare that with, To stop the movie, type "stop". in which the command does not include a period. (The demonstration sentence is not part of the software specification). The reason the illogical convention is used is because typographers disliked the appearance of many consecutive punctuation marks. In the context of writing dialog, such care was not necessary. HARDWARE REQUIREMENTS This specification assumes implementation on a standard PC or Macintosh computer. The system can be used with any standard English IBM or Mac keyboard and with the keyboards of many or all other phonetic languages, however for operation with true Leap keys, a keyboard with at least two thumb-operable buttons under the space bar is required. At present, the recommended keyboard is the IBM "Trackpoint USB Space Saver Keyboard - Black (US English)". List price $99. Model Name: 22P5150(this number is also referred to as the "Marketing Part Number"). The keyboard-mounted mouse buttons will be referred to as Leap> and Leap<. Versions of this keyboard for other languages may be available outside of the U.S.A. Operation without a special keyboard is less efficient and takes longer to habituate to. But, even so, THE is entirely practical and more efficient than conventional editors. In this document we will refer to the keyboards without LEAP keys as "standard keyboards" and those with two keys below the space bar as "LEAP keyboards". DISPLAY OF THIS DOCUMENT This document should be displayed in a monospaced font such as Courier so that character illustrations and charts will appear correctly aligned. This version is designed to maintain its meaning even if emailed as text. OPERATING SYSTEMS The demo we are creating should eventually run under Windows 95, Linux, and Mac OS 8.5 and later, including OS X. The LEAP keyboard noted above requires OS 10.2 or later or a separate USB driver such as USB Overdrive (a shareware package). This specification does not describe the installation or use of USB Overdrive on earlier Mac operating systems. The methods that use standard keyboards will work with earlier Macintosh operating systems. As of V 68, the software is being reworked so that this paragraph will soon be obsolete. The use of the specified keyboard (detailed below) is strongly advised. It makes learning and using THE much faster and easier. BIBLIOGRAPHY It is recommended that you have read Norman, Donald, "The Design of Everyday Things" Basic Books, New York. 1988 Raskin, Jef. "The Humane Interface" Addison-Wesley, Boston. 2000 to understand the motivation and design principles underlying this specification. The Raskin book is abbreviated "THI" in this specification. NOTATION OF KEYS, KEYSTROKES, AND QUASIMODES Keys with names such as Space, Delete, Tab, and Return are written with the first letter capitalized and the following letters in lowercase. Because the up and down arrows used for key operation notation in THI are not available in ASCII, the backslash after a key name (\) indicates the named key going down, and the slash (/) after a key name indicates the named key going up. Thus, to type a capital "A" on a normal keyboard (or even on a typewriter), you'd perform this sequence of actions: Shift\ a\ a/ Shift/ Note that individual letters always appear in lower case in this notation. We will not use "/" or "\" as characters in our examples. The act of pressing and releasing a key with no intervening actions is called "tapping" a key. Sometimes we abbreviate the notation from a\ a/ to a\/ where this abbreviation will cause no ambiguity. The act of holding Shift for as long as you wish to type capital letters is said to establish a "quasimode". It is not a mode as it vanishes as soon as you release the Shift key. For further details of this notation and nomenclature see THI pp 35 ff. The key labeled "Delete", "Backspace", or "Erase" that appears (usually in the upper-right corner) on various keyboards will be called the "Del" key here. "Leap" refers to either the LEAP forward ("Leap>") key or the LEAP backward ("Leap<") key. In any single keyboard expression Leap stands for Leap> or Leap<, in every instance. For example Shift\ Leap\ Leap/ can mean either Shift\ Leap>\ Leap>/ or Shift\ Leap<\ Leap\ Leap/. The action of LEAPing is written with all uppercase letters to distinguish it from the Leap keys. The variable names and notations in this specification are used only to clarify and simplify the specification; they are not suitable for or intended as program variable names, which are typically designed to be self-documenting to a greater degree than are single letters. STICKY KEYS AVOIDANCE Some systems, such as Windows and the Mac, have an accessibility package that changes their quasimodes to modes to accommodate users who cannot hold one key while typing another. This has a number of implications for this system. At very least, we have to notify users to turn off such packages before they run this one. Better, of course, is for our software to turn off or ignore such packages and then restore their use when people leave our environment. Lastly, we should consider a "sticky keys" version of our own system for use by users who need such a facility, recognizing that such an implementation will be slower and far more error prone than THE. There are no time dependencies in THE that a user has to adhere to, so that a user can operate as slowly as necessary, without fear of features timing out. There are no "double clicks" or other operations that require rapid motor control, and a mouse is not required for dealing with text. Thus THE is suitable for many users who cannot use a standard editor, even given the usual accessibility features. TIMING While we do not have timing constraints on user actions, we have some important minimum speeds with which the computer has to respond. Whenever the user is entering text, under whatever circumstances, the characters typed should appear within 50 msec of the time the key is pressed. This time is chosen so that the fastest human typist will not feel that the computer is getting behind them. When any command is issued or any process started, a response should be made within 250 msec.that is, fast enough so that the user doesn't have time to make another action in the belief that the system has gone awry. See THI for information on reaction times. If the operation cannot be completed in 250 msec, then an artificial response -- such as a transparent message saying that the system is working on the action, and how long until it will take (if the system can predict accurately) -- must be generated. If the system cannot predict the delay, then (unlike many of today's systems) it should just tell the truth:"This will take a while, but I don't know just how long.". What it must not do is put up an inaccurate progress bar. STRUCTURE OF THE TEXT A character in memory is represented by a 16-bit Unicode value. The master document, or "text" is a vector of z+1 characters, notated V(0), V(1), ..., V(z). These are considered logically contiguous from the user's point of view, though they may not be contiguous in memory. A character may be an image, e.g. a photograph. This will be specified further below. The cursor, which is represented on the display by a blinking rectangle, is associated with exactly one character, V(c). 0 < c < z + 1. A "block" of text is a logically contiguous group of k>=0 characters. A block of length 0 is called an "empty" block. A non-empty block of length k>0 that starts at V(n) consists of the set of k characters, V(n+0), V(n+1), ..., V(n+k-1). Any block of k characters can be represented by the interval of pointers, (n, n+k-1). Several special characters are known as "boundary" characters. They are the "Return" character, the "Page" character, and the "Document" character. Each denotes the boundary between two (possibly empty) blocks of text. In particular, they serve to break the text up into logically contiguous blocks called paragraphs, pages, and documents respectively. A higher-level "folder" character is not needed because the user can compose higher-level groupings of documents by simply creating sequences of two or more adjacent document characters as boundary pseudo-characters to denote any higher level groupings the user might want. This has proved to work well in previous versions of this software. A "document" is defined as a possibly empty block of characters that consists of a contiguous set of non-document characters delimited at both ends by document characters. The document characters cause the following character to print (on paper) on a new page. There is also a command (Page) which inserts a page character. This starts a new page without its being the beginning of a new document. The first and last characters of the text, V(0) and V(z), are always present in the text and are permanently set to document characters that function as boundary delimiters for both the user and the internal implementation algorithms. Neither can be deleted. Thus z>=1 is always true and the text always consists of at least 1 document. Additional boundary characters may appear anywhere within the internal block of characters. The minimal state of the text consists of nothing but two document characters, V(0) and V(z=1). For now, the document character is typed as an accent grave (pronounced "grahv" with a short 'a' sound as in "aha"). This character was chosen as it is seldom used and can be used in text and in search patterns with a standard keyboard, being lower case. The document character should have as its appearance a horizontal dark gray bar across the text environment. A command "grave" will place an isolated accent grave that is not a document character into the text should one be needed, and such an accent in the search pattern will match document characters or the rare use of such an accent in isolation.Use of an accent grave on a character is neither a document character nor the accent grave character. In localizing THE, other characters may have to be chosen for this function. The initial state of the text contains the Documentation document, the Deletions Document (to be defined below), the Messages Document, and perhaps other material bounded by document characters. These may be optional or empty or automatically created the first time they are needed. The Deletions Document is always the last document in the text. The number of documents in the text is equal to one less than the number of document characters. If there is no room for more characters in memory, each character typed has no effect other than causing a warning signal to sound and an appropriate message to appear. In modern systems, which can have hundreds of megabytes of RAM and can spool off text to a non-volatile, high-capacity storage device, this is a highly unlikely event. CLEANLINESS When a user deletes any object that has associated state information, THE should clean up any saved state and/or preference files. When fully implemented, any such information should be just another document, so that there are never any auxiliary files. We should never clutter memory or mass storage. No memory leaks either. THE CURSOR The cursor is associated with exactly one character in the text. The cursor is initially on the last document character before any of THE-supplied documents. The cursor's appearance will be a blinking transparent rectangle the height and width of the character on which it sits, and of a color defined below. It blinks at a rate of approximately three times per second with a 50% duty cycle (on and off times have equal duration). THI explains why the customary between-character cursor is not used. RESTORATION OF SYSTEM STATE The state of the system, when it has been turned off or slept and then turned on again, is whatever state it was in when it was turned off or entered into the sleep state. The saved appearance, which reflects the saved state, includes cursor position, selection markings, and all other indications of state. In other words, the way it looked when you left is exactly the way it looks when you return. Ditto for the way it worked. CURSOR AND SELECTION: EXAMPLES There are two basic conditions associated with characters. The first is the cursor. Characters not normally visible, such as Space and Return are visible when the cursor is on them, when they are selected, and when in the LEAP or Command quasimodes (to be discussed below). In this document, the cursor is indicated by an asterisk under a character. abCde (1) * Example (1) is a five-character string with the cursor on the letter c. There is always exactly one character with a cursor: in the case where the text consists of only two document characters, the last document character has the cursor on it. This blinking cursor always shows exactly where the next character you type will appear, the place to which the cursor points is therefore also called the "insertion point". That the cursor blinks is quite important in directing the user's attention to the insertion point. In justified or centered text, the cursor may not show exactly where the next character will appear, although it will be close, as the line of text in which the cursor resides may move slightly as each character is typed. In practice this does not cause confusion. There is also a selection, which will be indicated in this document's notation by one or more letters being capitalized. The selection is represented on the display by a colored highlight. When only one character is selected and the cursor is also on that character, we say that the cursor and selection are "collapsed" on that character. Sometimes we use the shorthand phrase that "the cursor is collapsed" to mean that both a one-character selection and the cursor are on the same single character. TYPING AND ERASING: EXAMPLES Typing an x when the text is abCde (1) * results in abXcde (2). * The selection (X) is exactly what would be erased if you were now to tap Del. There is no forward erase in this design. By not having a forward erase, we eliminate a Hicks' law delay. Nonetheless, we might consider testing Shift Delete as forward delete as an experiment. (see THI for an explanation of Hicks' law.) Note that when you delete or erase a character, it is not lost, but put into the Deletion Document, which will be discussed below. Here is a more complete description: if the cursor and highlight were collapsed on the letter c in the string abcde, you would have abCde (1) again. * On the display, a blinking cursor on an unselected character is easy to distinguish from a blinking cursor on a selected character as in the first case it blinks from the cursor color to the background color (usually white) and the selection sits alongside it, and in the second it blinks from the cursor color to the selection color. See the section COLORS below for the RGB designation of the colors. If you type x when the text is as in (1), you get abXcde (2) * continuing by typing y, you obtain abxYcde (5). * With the situation as in (5), a tap of the Del key gives state (2) of the text. In other words, Del exactly undoes typing. This is always true, even if the character is a Tab, Return or other non-alphanumeric character. From state (1) abCde (1), * a tap of Del results in aBde (3). * Separating the cursor from the selection is necessary because if you tap Del again, you clearly want to delete the letter preceding the c, so the b must be highlighted. However, if you want to restore the previous state by typing the letter c, it must appear where the D is (the D will, of course, move over). The split cursor allows explicit designation of both exactly where the next character will appear and exactly what will be deleted if you tap Del. The usual, between-character cursor is not explicit, especially when it is positioned at the end or beginning of a line. With the present cursor design, the selection can be on one line and the insertion point on the next, both clearly indicated. CREEPING AND LEAPING: EXAMPLES How LEAPing is accomplished is discussed below. It is a method of moving the cursor to a given character. Its speed advantage over the mouse or any graphic input device for pointing in text is considerable (see GOMS modeling in THI for quantitative measures). In those cases where you don't have to look for but know where you want to LEAP to, you save the visual searching (which can involve using scroll bars) time; in such cases LEAP can be easily 10 times faster (1.2 seconds instead of 12 seconds) than using a mouse. Creep, which consists of moving the cursor one character at a time, is accomplished by tapping either Leap key. With a standard keyboard, the left and right arrow keys (cursor control keys) perform this function. Starting from the situation in example (5), abxYcde (5) * a LEAP left to the letter b gives us aBxycde (6). * A tap of Del in example (6) yields Axycde (7) * indicating, as usual, that the next tap of Del would delete the a. The next letter typed would appear where the X is and the X and following letters would move out of the way. If the example were a longer text, inserting and erasing characters might cause word wrap or word unwrap to occur at the ends of lines. The cursor and single-character selection are either on the same character or, in left-to-right languages, are on adjacent characters with the selection to the left of the cursor. From this situation zAxcde (4) * a creep right collapses to the right zaXcde (8) * indicating that you can delete the X, or type there, as you please. Alternatively, a LEAP to the right to "x" from zAxcde (8a) * would also yield state (8). LEAP to the right proceeds with its search starting on the character immediately to the right of the cursor. LEAP to the left proceeds with its search starting on the character immediately to the left of the cursor. A creep right from zaXcde (8) * gives us zaxCde (9). * A creep left from (9) just moves the cursor and selection and returns us to (8). Typing Z in (9) results in zaxZcde (10). * We have seen what a creep right does. A creep left from (10) collapses the cursor to the left and gives us zaxZcde (11). * A creep always collapses the cursor and selection. If we had LEAPed left to z from (10) the cursor and selection also end up collapsed on the Z. zaxZcde (11). * DOCUMENT CHARACTERS I will use q to stand for the document character (created by typing an accent grave) and start with the text q Abcde * q (12) as if we had just LEAPed or crept to the A. There are four things that the user could do next: type erase creep (or LEAP) left to the document character issue a command. We know what typing will do. Erase gives us Q bcde * q (13) Erasing from state (13) makes no change at all. You cannot erase the initial document character even though it is highlighted. If it were not the initial document character, it would behave as any other character that happened to be the full width of the display. Creeping left will have no effect, either. Typing an a from state (13) will give us q Abcde * q (13a). LEAPing right from state (13) to the other document character gives you q bcde Q (13b) * with the cursor on the ending document character. Note that the final document character is highlighted; this is important for selection. If Del is now used, the document character is not erased. More consistently, a user's mental model is that it is erased and immediately replaced, because the highlight moves back one to the E. Note that we are discussing here only the initial and final document characters. Document characters in the midst of text behave as do any character, and can be typed and deleted freely. For example, you can combine two documents by deleting the document character between them. Back to our example. After the LEAP to the final document character we have: q bcdE q (13c) * It is important that LEAPing left from state (13b) q bcde Q (13b) * to the first document character leads to (13d) Q bcde * q (13d). We shall see why having the initial document character selected is important in the section on Selection. Note that even though the highlight is on the initial document character, the document character cannot be erased by tapping Del (or by any other means). In the case of multiple documents in a single environment, LEAP will use the circular search discussed below. THE HUMANE QUASIMODE (for LEAP and with dedicated LEAP keys) There are two LEAP keys on such a keyboard, located centrally below the space bar. They are LEAP backward (Leap<) and LEAP forward (Leap>). The LEAP quasimode exists for as long as either LEAP key is held down. THE HUMANE QUASIMODE (for LEAP with a standard keyboard) Just as Shift\ establishes the uppercase quasimode that exists until Shift/ occurs, the LEAP quasimode on standard keyboards is created by Shift\ Space\ Space/. In other words, the quasimode is created by a press of the Shift key followed by a tap of the Space bar. and it persists as long as the Shift key is held down. The LEAP quasimode remains in effect until Shift/. In some systems, such as some of those used for inputting Chinese, Shift\ Space\ Space/ Shift/ is used for changing between modes, however THE always has at least one additional character typed while in the quasimode, allowing a system to distinguish between the Chinese mode shift and a THE quasimode. THE COMMAND QUASIMODE (for either keyboard type) The Command quasimode exists for as long as the Command key is held down. The Command key is usually the one called "command" by the manufacturers (the Apple or Windows logo keys), depending on the keyboard layout. ARGUMENTS FOR AND AGAINST HAVING TWO LEAP AND COMMAND METHODS Should we require users to obtain a LEAP keyboard and abandon the standard keyboard hack? The true Leap key interface is easier to learn and faster in performance than the standard keyboard version. True LEAP keys allow the use of upper- and lowercase letters in patterns, and can distinguish between pairs of characters on the same key, such as 2 and @. Also, we would have to implement and maintain only one version. The (slight) complexity of the standard keyboard version might prejudice newcomers against THE. On the other hand, the standard keyboard version is just software and gives most of the benefits of THE at lower expense, and allows it to run on many systems for which an appropriate keyboard is not available. As for maintaining a version that supports both, it violates monotony unless we have the software turn off the interface that is not being used (not with a user preference, but automatically by sensing whether the first few LEAPs are via one method or the other, and then disabling the one not used). The sensing can be done whenever the machine is turned on or THE invoked. In later systems, of course, THE will not be invoked as it will be the basis for other software. We will cross that happy bridge when we come to it. For now, this specification requires that both methods must be operational. In any case, LEAPing, whether invoked by one method or the other, works the same and the following descriptions apply. INDICATION, PRESELECTION, SELECTION, AND THE ANCHOR Say you have abCdefghij (14), * and you LEAP to the h. Using an underline to indicate what will be selected (if you were to tell THE to make a selection), you have the situation abcdefgHij (15). * As soon as you LEAP, the "c" becomes an anchor, which means that it anchors or marks one end of what would be selected if you were to use the select command. As the LEAP ends on the "h", the "h" becomes the other anchor, marking the second end of what would be selected. The underlined letters, cdefgh, are the preselection, as they are what would be selected if you were to subsequently use the select command. The preselection is indicated (see THI pp. 105-106 for more information on indication, which is any method that shows, ahead of time, what will be affected by certain commands). Preselection should probably be displayed by an underline (just under where the usual text underline would go) in the selection color. It will then appear that indication expands upward to become selection. (temporarily, we are using a yellowish highlight for this). The indication highlight is visible only during the quasimode otherwise the display becomes visually cluttered and confusing. Besides, you only need to see the preselection when you are about to issue a command, and you can always establish the LEAP quasimode to see it. If you do not want to use that preselection, you can abandon the quasimode just by releasing the key that established it without having to cancel or take any other action. Selections, unlike indication, persist after the quasimode is released. As we have seen, a selection has two anchor characters (or, simply, anchors). A second anchor is established by a LEAP, and it becomes a first anchor when you perform your next LEAP, but a second anchor does not become a first anchor when you use the repeat command or any command that repeats a previous LEAP. Those commands can therefore extend or contract a selection as they move only the second anchor. Anchors may be moved by collapsing the selection to one of the anchors and using Creep. In this case the anchor collapsed to will follow the cursor. If you use the select command (s in the standard keyboard, tapping both LEAP keys at the same time in the LEAP keyboard) while in the quasimode you will select whatever was indicated: proceeding from (15) abcdefgHij (15), * you will have abCDEFGHij (16). * Note that the cursor is on the character immediately after the selection. If, instead of (14) abCdefghij (14), * you had had abCdefghij (14a) * the LEAP to H would result in abcdefgHij (15a). * Creeping to the right from state (16) abCDEFGHij (16) * can be used to prepare to make a larger selection. The creep collapses the highlight onto the i, with the cursor moved over to the i (state (17)). This allows you to type to the right of the selection (rather than in the middle of it). abcdefgHij (17). * As you creep, the indication color shows that the potential selection includes the crept-to characters. Another tap of creep to the right, followed by using the select command, gives you a larger selection. abCDEFGHIj (18) * Tapping the left arrow key (on a standard keyboard) or the LEAP< key from state (18) collapses the selection to the left. abCdefghij (19) * . Creeping to the left from (19) results in aBcdefghij (20) * , and selecting now gives you this (as would have been shown prior to selection by indication): aBCDEFGHIj (21) * Of course, you could also creep right from (19) and move the left anchor of the potential selection to the right, and the indicated text will shrink accordingly. You can shrink the indication down to nothing and then, if you continue to creep, the indication will grow, extended to the other side. In general, when the selection encompasses more than one character, a creep to the left or right moves the cursor so that only the left or right (respectively) end of the selection is now selected. The cursor is on the highlight when collapsing to the left, and not on the highlight when collapsing to the right. Then you can continue to creep so as to put both highlight and cursor on a different character. After creeping, you may select (assuming you do not lose the anchor by typing or other action) and you will highlight everything from the unadjusted end of the selection to the character to which you have just crept. Also, in general and at all times, the indication when made visible shows what would be selected if the select command were given. Below, we will not always mention indication but when we show what selection results, the characters selected would have been previously indicated. When LEAPing to the left when the cursor and highlight are not on the same character (in other words, this never happens immediately after a LEAP) the selection extends from the highlighted character, not from the cursor position. From abCdefghij (14a) * a LEAP back to "a" results in Abcdefghij (14b) * , with bc indicated (The cursor and highlight supercede indication). The select command then gives ABCdefghij (14c) * It is important that the "d", on which the cursor was blinking not be included in the selection. First of all, selection should not include the character at the position at which the next character was to have appeared. Second, a LEAP over a span of (in this case) three characters should result in the same selection both forward and backward. Thirdly, if you type, say "abc" and then LEAP back to the "a", you should get only "abc" selected. Earlier we started with having LEAPed or crept to the final document character q bcde Q (13b) * and then LEAPed (it's a bit far to creep) to the initial document character Q bcde * q (13d) Selecting now gives you Q BCDE Q (13e) * Namely, everything is selected. This state is useful when you want to copy a document including its document characters. Deleting the selection results in Q q (13f) * SUMMARY TABLES OF CURSOR AND UNEXTENDED HIGHLIGHT ACTION The cursor and unextended highlight can be in one of two states. Either they are both on the same character: rSt * (23) or they are split onto adjacent characters such that the highlight precedes the cursor by one character: Rst * (25) Typing and erasing operate as shown in tables A and B -- in each case starting with the indicated initial state and performing one of two operations on it: TABLE A Initial State Type 'x' or Tap Del abCde abXcde aBde * * * aBcde abXcde Acde * * * TABLE B Initial State Creep Left or Creep Right abCde aBcde abcDe * * * aBcde aBcde abCde * * * The following tables describe LEAPing and Selection, and show consecutive actions rather than alternate actions in the successive columns. TABLE C Initial State LEAP> to x then Select aBxde abXde aBXde * * * aBdexf abdeXf aBDEXf * * * Abxde abXde aBXde * * * TABLE D Initial State LEAP< to x then Select axBde aXbde aXBde * * * xaBde Xabde XABde * * * axBde aXbde aXBde * * * LEAPing is similar to creeping in that the selection and cursor both end up on the first character of the target. They differ in that creep (and LEAP again, to be discussed below) extend the indication whereas LEAP resets an anchor. LEAPING TO LONGER PATTERNS Say that we have this text: These theaters think that those thespians thank them * (30) (This discussion will be described in terms of a Leap keyboard, but it also applies to a standard keyboard: Just replace Leap>\ with Shift\ Space\/ j\/ in each occurence.) Typing Leap>\ t\ (31) yields these Theaters think that those thespians thank them * (32) Note that neither Leap> nor t have been released. If you now type t/ h\/ (33) The cursor will not move as the pattern "th" matches the "th" in "theaters". Note that you have not released Leap> If you now type o\/ (34) the cursor will move to the "t" in "those": these theaters think that Those thespians thank them * (35) skipping over the "th"s in "think" and "that" because the first instance of "tho" occurs in "those". Leap> has still not been released (you would release it if (35) were the desired state). If, while still holding Leap> you type Del\/ (36) this will delete the last character from the pattern (the "o") restoring the pattern to as it was after (33), and the cursor will jump back so that we are again at example (32). This demonstrates that you can correct a pattern "on the fly". It takes a while to get used to having this ability, but it is wonderful to not have to complete a search and only then find that it is in error. You can use Del\/ repeatedly to completely erase the pattern and cancel the LEAP entirely. Another way to cancel the LEAP is to just hit a bunch of keys, creating a pattern that might be "thol;jk" which doesn't match anything. Banging on the keyboard also releases any frustration you might have had. But say you had typed the pattern "th" so far, were still holding Leap>, and were back at example 32: these Theaters think that those thespians thank them * (32) From this situation, then, typing i\/ would move the cursor to the "t" in "think" typing e\/ would not move the cursor typing e\/ m\/ would move the cursor to the "t" in "them" typing e\/ s\/ would move the cursor to the "t" in "thespians" typing a\/ would move the cursor to the first "t" in "that" typing a\/ t\/ would also move the cursor to the first "t" in "that" typing a\/ n\/ would move the cursor to the "t" in "thank" typing e\/ a\/ t\/would not move the cursor typing e\/ a\/ Del\/ s\/ would move the cursor to the "t" in "thespians". At last release the Leap> key Leap>/ after any of these patterns and the cursor will stay put. Starting again from example 30 These theaters think that those thespians thank them * (30) say that you wanted to move the cursor to the final (rather than the first) "t" in the word "that". You would type Leap>\ t\/ Space\/ Leap>/ Starting yet again from example 30, this time desiring to move the cursor to the final "s" in "thespians", you would begin by typing Leap>\ s\/ Space\/ (37). Keeping your eye on the final "s" in "thespians" you'd notice that the cursor is not there, so you keep on typing what you see there: t\/ h\/ and finally, when you type a\/ you distinguish "s tha" from the earlier "s thi" and the cursor appears where you want it. So you let go Leap>/ and you're done. SIDEBAR: To the reader who's worked through all this detail. Writing how THE works all out in detail makes LEAPing seem like a tedious procedure -- but so would writing out how you use a mouse. For example: Move your hand from the keyboard to the mouse, move the cursor up by moving the mouse forward, down by pulling the mouse toward you, and move the cursor right and left by moving the mouse in the corresponding direction. Move the cursor to the left of a letter you wish to insert at or to the right of a letter you want to delete, and then click the mouse button. Move your hand back to the keyboard and proceed. Explaining click-and-drag and so on would take up pages. I know this because I wrote the original spec for that interface too (that was before most people had even heard of a computer mouse). At the time, it sounded just as strange and complicated. Now people call using the mouse "natural" and "intuitive." When you've used LEAP with the LEAP keyboard for even a few days, going back to the mouse feels like you've had to go back to a prop plane after flying a jet. In practice, when you are showing someone how to use LEAP, it takes only a few seconds, and then not too long to get to the point where LEAPing feels "natural" and "intuitive". End of SIDEBAR In practice you simply look at your target and then, while holding Leap> you type the letter you want the cursor to be on and any letters or symbols that follow it until you see the cursor land on the desired location. For example, we can put many of the lines shown above into this brief description: To move to the final "s" in "thesbians" press the LEAP> key and type s tha and there you are. Incidentally, leaving go of the LEAP key is automatic and does not have to be taught to most people. LEAPING TO ENDS OF LINES Say that you had this situation You say what you say i say what i see With the cursor on the first letter of the first word and you wish to LEAP to the "a" in the second occurence of the word "say". LEAPing to "ay" would not get you there, but LEAPing to "ay" would. In THE, Return is a character just like any other. To LEAP somewhere, you type the pattern just as you would type the text. You need not learn any tricks to put a Return into a search string.xxxx INSERTING CHARACTERS BY TYPING, MORE DETAIL When the cursor is at V(c) and a character is typed, then either (0) c=0 or (1) c>0, unless the cursor is in locked text, in which case see (3), below. (0) If c=0, move c to 1 and continue with step (1) (the initial sentinel document character cannot be deleted or moved or replaced, so all text input must occur after it). (1) If z cannot be incremented by 1 (i.e. there is no room for more characters in free memory), the character typed has no effect other than causing a warning to sound and an appropriate message to appear. Otherwise, increment z by 1 and then set V(j) to V(j-1) for j=z down to but not including j=c (note that if you do the loop forward, it won't work). Continue to step (2). (2) If step (1) successfully incremented z, increment c by 1. In other words, newly typed characters appear at the cursor position, and force all characters at or above that position "forwards" in the text. The cursor moves forward also, so that the next typed character appears just after the previously typed character in the text. (3) If the cursor is in locked text (explained below), and the user types, then the typing appears just after the locked text. If necessary (when the end of the locked text is not visible in the display) the position of the text with respect to the display is adjusted so that the cursor is visible. AUTOREPEAT AND ROLLOVER IN TYPING Autorepeat should function as described in THI (p 185). Research as to whether this is possible on present systems will have to be undertaken. This is not essential in a first implementation where we will use standard autorepeat as provided by the underlying system. If one or more keys (other than quasimode keys such as Shift) are held down and an additional key is pressed, the effect is as if the other keys had been lifted and the last key pressed. This is called "n-key rollover" It is presently built into most keyboards or keyboard drivers, but in case we have to re-implement it, this specification is given. N-key rollover allows fast typists to type rapidly without worrying about fingers lagging on keys that have already been pressed. Here is an explicit example of two-key rollover: In ordinary typing we accept, for the string "ab" either a\ b\ a/ b/ or a\ a/ b\ b/ APPEARANCE OF THE TEXT ON THE DISPLAY The text is displayed either on the entire screen or within a window dedicated to this system. A character, at least for now, is thought of as being a rectangle of pixels. It is bottom-justified to other characters in the line, with the usual word-wrap rules applying. If a picture is inserted into the text, it behaves as any other character would, except that (at least for now) it cannot be LEAPed to. In future implementations we may allow searches for a matching picture in a LEAP (by pointing to an instance of the image and using it as a pattern; other more sophisticated approaches are possible). Text in Western languages is displayed conventionally, broken up into horizontal lines. When a character being typed or inserted would cause the length of the line to exceed the width of the display area, word wrap, as with almost all word processors, is employed. One or more spaces at the end of a line (at and beyond the position at which the typing of the thinnest character would cause word wrap) are noted internally and stored, but are not shown unless the system is in the LEAP quasimode, and only one is shown (there is not room for more). Typing a return (the key is marked Enter on some keyboards) does not cause word wrap. In left-to-right languages the character following a return appears at the left end of the next line. To make sure that there is room for the return character (or other normally hidden characters when visible) at the right end of a line, text cannot be set closer to the right edge of the display area than the width of the widest normally hidden character. We do not want the display to rewrap when an area is selected. A word that is longer than a line is not wrapped. Instead, it is broken at the end of the line and the excess characters are moved to the next line. The present implementation will not do hyphenation. In particular, if a word is longer than a line, it begins after the spaces following the previous word and on the same line as the previous word (unless there is no room, in which case it starts on the next line as any other word would.). For example, here is a word consisting of all qs that is longer than a line. The lines are short in this example. Here comes a long word qqq qqqqqqqqqqqqq qqq followed by other words. Spaces are shown as a special symbol (such as a dot at mid-height) when selected. If typing a character causes a word to wrap to the next line, then erasing that character causes the word to unwrap back to the previous line. The two operations, typing and deleting, are strict inverses of one another in the humane editor. (This is not always the case with typical systems, for example, typing Tab will move you to the next field, but Del will not get you back.) After a Return or a Page character has been typed, the cursor moves to the leftmost position of the next line. If a return or any break is typed when the cursor is on the bottom line of the display, then all lines on the display are moved up two lines, the two top lines disappear from the display, and the cursor is placed at the leftmost position on the bottom line, under the break. The move up two lines is necessary because the cursor will split onto two lines as you will see when you try THE, and as described in THI). When the cursor is on a Page or Document character, its position within the symbol is at the left margin. A Tab character, when selected, is shown as a bold arrow pointing to the right (to the left in left-to-right languages). APPEARANCE OF THE CURSOR The cursor will be the rectangle of smallest width that covers the space required by the character on which it sits. It is the height of the tallest character in the current line. The cursor flashes at a rate of three times per second with a 50% duty cycle. USER NOTIFICATION (User Alerts, Messages, Warnings, Advisories) We will use transparent messages (see p 117 in THI) that disappear as soon as you continue to work or if they are no longer necessary. As you can work right through them they do not obscure the content of the display nor do they lock up the computer in a message mode as a conventional dialog box does. If a message needs a reply from the user, it can say something like, "type and select your desired response, then use the 'reply' command". The best strategy is to design so that messages are not necessary. A warning message should be accompanied by a sound, perhaps a reading aloud of the message (which reading is stopped by any user action). All warning (as opposed to standard) messages that appear are added to the front of the Message Document, separated from each other (as with multiple-character deletions in the Deletion Document). Thus they accumulate with the most recent message first. See the discussion under Delete, below. The idea here is that, like text, messages are never lost, but can be referred to at a later time. Messages in the Message Document can be deleted, moved, etc. as with any other text. HOW TO INVOKE LEAPING As has been discussed above, the cursor can be positioned at any character without having to move through or across intermediate characters by the technique of LEAPing. LEAPing allows users to keep their hands on the keyboard when dealing with text. LEAP unifies cursor moving (usually done with a mouse) and text searching (usually accomplished by opening a dialog box and typing in a search pattern). One mechanism supplants two and is faster than either. As noted above, dedicated LEAP keys, especially if placed below the space bar so that they can be operated by your underutilized thumbs, create an ergonomically superior interface. Assume that the selection's last (highest indexed) character is at V(i) and that somewhere in the document is a block of characters B(1), B(2), ..., B(n). I will use the notation B(j)\ B(j)/ to indicate that the key corresponding to the character B(j) is pressed and released. Typing (standard keyboard) Two keys are used to indicate whether LEAPing is to be forward or backward. To make this choice of key language independent, we use the two keys under the index and middle fingers of the right hand when it is on home row. In the US, these keys are "j" and "k". More on why these were chosen is explained below. These two keys, whatever they are labeled on the keyboard, will be notated "<" and ">" respectively in the following discussion. Thus Shift\ Space\ Space/ >\ >/ would be typed, in the U.S. as Shift\ Space\ Space/ k\ k/ and Shift\ Space\ Space/ <\ " do not represent the less-than and greater-than signs. Shift\ Space\ Space/ >\ >/ establishes the forward LEAP quasimode -- which is a special case of the LEAP quasimode. Another way to say this is to get into the LEAP quasimode and then type ">". Shift\ Space\ Space/ <\ \ establishes the forward LEAP quasimode. LEAP<\ establishes the backward LEAP quasimode. In the LEAP Quasimode Once either LEAP quasimode is established, it immediately causes all hidden characters to become visible. Spaces become small dots at about one x height, returns become paragraph symbols, and tabs become bold right-pointing arrows. In addition, the transparent text "LEAP forward" or "LEAP backward" appears on the display in large letters that overlay but do not obscure the text. In the LEAP Ahead quasimode, typing B(1)\ B(1)/ where B(1) is a displayable character, causes the cursor to move to the first occurrence of B(1) in the block V(i+1), V(i+2), ..., V(z). B(1) is the "pattern" being searched for in this case. If no occurrence appears in that portion of the document, the search continues with V(1), and continues to V(i-1) -- this called "circular search". If the pattern is still not found and while the quasimode is held, the system moves to the next document, and so on, treating the entire set of documents circularly. If no instance of the pattern is ever found, the system waits for as long as the quasimode is in effect. When the user releases the LEAP quasimode, the system gives a visual and audible indication (e.g. a screen flash and an audible signal (a descending diminished 5th) that nothing was found. If you continue adding letters to the pattern after the first signal, each letter will cause a further signal. If you delete letters from the pattern, each delete will beep until you get back to a pattern found in the text. If, however, the first character matches something in the text and the user types a second character while still in the forward LEAP quasimode B(2)\ B(2)/ Then the search restarts from V(i+1) using B(2) concatenated with B(1) as the pattern, and following the same search path. In the implementation, speed can be improved by saving a list of found occurrences of B(1), for example V(b1), and then just looking at V(b1+1) to see if it matches B(2). The same is done for each character added to the pattern. When a match is found, say at V(f), and the user sees that this was the desired instance and releases the Shift key, then the cursor remains at V(f). In such a case the operation is called a "successful LEAP". LEAP back is the same, except that the on-screen transparent message says "LEAP Backward", the search begins at V(i-1) and decrements its way through the current document, circling back to the end if necessary. If there are multiple documents, then after the search has proceeded through the current document it searches through the preceding document and so on to the first document, after which it wraps to the last document, and any following documents that are behind the current document. In brief, if a search for ThisPattern is desired, the user types, for LEAP ahead on a standard keyboard (recalling that "<" stands for "j" on a US keyboard or whatever character is operated by the index finger of the right hand on home row and that ">" stands for the character operated by the middle finger of the right hand on home row. Shift\ Space\ Space/ >\ >/ ThisPattern Shift/ For LEAP back Shift\/ Space\ Space/ <\ \ ThisPattern LEAP>/ For LEAP back LEAP<\ ThisPattern LEAP 1. If a discontiguous selection is moved, what appears in the place moved to is the concatenation of the parts of the selection, in the order in which they appeared in the text. In the case of SWAP (which is the most difficult case), when both selection 0 and selection 1 are discontiguous, each discontiguous selection is concatenated into a single block of text, Selection 0 is inserted at the location of the first (nearest the beginning of the document) part of selection 1, and selection 1 is inserted at the location of the first part of selection 0. Other commands where one or the other selection is discontiguous work to the same rule. CALCULATE COMMAND Co = CALC The "calc" command, given a selection S that represents an arithmetic expression (for now, in Python syntax because it is similar to standard notation and it is easy to implement), creates a new selection, S', that represents the result of the calculation. From the user's point of view, the selection S is moved to the Deletions Document and the selection S' is inserted in its place. An expression may include assignment to store its result in a variable (with Python variable name syntax) and can use variable names that were defined in a previously executed CALC in expressions. UNCALCULATE COMMAND Co = UNCALC The "UNCALC" command replaces any results in the selection with the stored expressions that created the results. The result that is replaced is first moved to the deletions document. DATE AND TIME COMMANDS Co = TIME Co = DATE Co = USDATE The comamnds TIME and DATE insert the current time (hh:mm:ss) and date (yyyy/mm/dd) into the text. A command USDATE would insert mm/dd/yy into the text. For other formats, other commands could be provided (this is better than having preference settings; the user has to learn only his or her preferred command). LEAPING TO A PATTERN IN THE TEXT Co = LEAP This command uses the current selection as a LEAP search pattern. This search is precisely case-sensitive. The pattern can easily include document and page characters. LEAPING TO A REGULAR EXPRESSION Co = LEAPR We should consider allowing LEAPs to regular expressions (Boolean searches with wild cards) in the text, but this is not a high priority. We might just show advanced users how to use a simple Python program for this kind of function. FAILED LEAPS If any LEAP fails due to there being no match in the text, an audible indication should be started immediately, while the LEAP quasimode is still in effect. This is necessary so that blind users can tell that a LEAP has failed, and for section 508 compliance. The indication is two brief notes forming a descending diminished fifth, the second note having twice the duration of the first note; if thought of as quarter notes, a good tempo would be quarter note = 160. FIND CURSOR COMMAND Co = FIND CURSOR If you have scrolled away from selection 0, this command gets you back. It positions selection 0 according to the display rules previously stated. It has been suggested that the FIND CURSOR command may not be necessary as tapping a Creep key has the same effect (though you have to remember to tap the other Creep key if you want the cursor in the same place as it was. However, use of Creep collapses the selection, which you may not want to disturb. REPLY COMMAND -- INPUT TO A RUNNING PROGRAM Co = REPLY When a program needs input, it sends a message and then waits until the user sends a reply to the program. The user does this by selecting the reply and then invoking the REPLY command. The programmer can, of course, create other input behavior, but you should never be forced to reply before proceeding with other tasks (that would be modal) although the particular program requesting input may not be able to proceed without the input. The system should not be rendered unusable just because a program is waiting for input as with so many GUI dialog boxes. If there are multiple programs executing, the REPLY command directs the input to the most recent notification. Again, the programmer can specify other behavior, or even supply a special REPLY command for their program so that the user can reply without having to respond to a later request for information first. The request for input should be specified by a transparent message. Executing the REPLY command leaves the selection selected. But obtain document SP0007 from Jef Raskin for further thoughts on this if you are interested in implementing this. TEXT APPEARANCE COMMANDS Co = ITALIC Co = REMOVE ITALIC Co = BOLD Co = REMOVE BOLD Co = NORMAL NORMAL removes all styles from the selection. A copy of the selection is put into the deletion document so that its formatting may be recovered if desired. Co = FONT NAME Co = FONT SIZE Co = ALL CAPS Co = NO CAPS Co = CAP EACH WORD Co = COLOR Co = COLORS causes a list of the available color names to appear (selected so that they may readily be removed). Other style commands, such as UNDERLINE and REMOVE UNDERLINE can be defined. When a character is typed, it assumes all the text appearance attributes that applied to the character the cursor was on just prior to typing. When a selection is moved or copied, each character retains the attributes it had prior to the move. The characters adjacent to its new position are not affected. PRINT COMMAND Co = PRINT In a single-printer system, this command prints the selection. The printed representation of the selection appears on paper as it does on the screen. Most notably, the printed representation of the beginning of the selection appears at a corresponding position on the paper, which is not necessarily the left margin. If the first characters of the selection are Document characters or Page characters, they are not sent to the printer. This prevents ejecting extra pages when you print a selected region that starts with, for example, a Document character or a Page character. If no printer is attached and the system can detect this fact, a beep sounds and a message is given in the usual fashion. PRINT should be interruptible by the STOP command and cancelable via whatever driver the printer company supplies. In multiple-printer systems, each printer has its own command, e.g. LASERPRINT, COLORPRINT, MKTPRINT, etc. and a command that allows setting up and naming such printer sets would be provided. By using separate commands, modality is avoided. A PRINTERS command could list all the printers available and annotate the user-relevant properties of each. UNDO COMMAND Co = UNDO The undo command undoes the last operation. Further invocations of UNDO continue to undo prior operations. Not everything is undoable, for example, Print. Attempting to undo a non-undoable command results in no operation taking place, except that the next undo will apply to the operation prior to the non-undoable operation. If undo is the first command used after a LEAP, the system is returned to the state it was in prior to the LEAP. The old pattern will be stored in the Old LEAPs Document. Undo depth is unlimited, except by limitations of physical memory. GRANULARITY OF UNDO What exactly is the "last operation" that the UNDO command undoes, that is, what is the granularity of undo? One answer is that UNDO undoes the effect of the last keystroke and takes you to the state the system had just before that keystroke was made, including screen appearance, cursor location, selections and all. Say a command has just been completed; not only would UNDO undo the command, but you'd be left with the partially typed command name on the display and the instruction to hold down the Shift key so that even the previous quasimode would be the same as it was. If you didn't follow the instruction, the UNDO would not take effect. This possibly solves the undo granularity problem, and makes the effect of UNDO strictly predictable, except for those operations such as printing which cannot be undone. REDO COMMAND Co = REDO The REDO command redoes the last UNDO, if possible. Repeated use redoes successively older undos, to the extent possible. If there are no more UNDOs to be redone, a message is given and the command has no effect. Of course at this point the text should be empty . PAGE COMMAND Co = PAGE This command inserts a Page character into the text. Page characters will appear as a full width graphic across the THE. They can be deleted just as with any other character. If convention weren't an issue we would probably want to call the Return key the "Paragraph" key, completing the analogy. The tilde will be used to type and search for Page characters. A command Co = TILDE can be used to insert an explicit tilde into the text; this works much like the document character. The Page character can be used as part of a search pattern as well. The system inserts implicit Page characters, a dashed line, so that the user will know where page boundaries will be if the document is printed. These cannot be LEAPed to or deleted. They are ignored when in the midst of a LEAP target, but are not ignored when part of a LEAP pattern TILDE COMMAND Co = TILDE Inserts a tilde into the text (not a tilde over a letter). Typing a tilde puts a Page character into the text, which is why we need this special command. We cannot use, instead, a "PAGE" command (or a "DOCUMENT" command, see below) because then there would be no way to put a page character or a document character into a LEAP pattern. Page and document characters are very often part of LEAP patterns. GRAVE COMMAND Co = GRAVE Inserts an accent grave into the text (not an accent over a character), just the character itself. The name of this command is a bit unfortunate as some people will pronounce it as though it was a hole to put dead things into, but the term probably OK for now. Typing an accent grave places a document character into the text. LOCK Co = LOCK Co = UNLOCK All text in the selection is locked by the LOCK command. That text is locked is shown by a special highlight. All text in the selection is unlocked by the UNLOCK command, and the special highlight is removed. Locked text may be LEAPed into and selected, but attempts to change the locked text or insert into it have no effect besides bringing up a transparent error message that says "This text is locked, and cannot be changed without first being unlocked." and which disappears at the next keypress. The importance of locked text cannot be overstated. Without it we cannot create forms, for example. TABS Co = SHOW TABS Co = SET TABS Co = CLEAR TABS Co = DEFAULT TABS Any selection may have a set of positions associated with it by means of the various tabs commands. These positions are called tab stops. A tab is a character of variable width that extends from the current cursor position to the next tab stop. A tab position is an integer from 0 to 99 inclusive, which represents a percentage of the maximum width available. The maximum width is the distance from the extreme left margin to the extreme right margin. Later, we will have commands such as "SET DECIMAL TABS" and other kinds of tabs as are conventionally available. Default tab stops are set at 5, 15, 30, 45, 60, 75, and 90 percent. Tabbing beyond the last tab stop on a line moves the cursor to the beginning of the next line. SHOW TABS inserts and leaves selected a list of tab stops in effect at the current cursor position. A list of tab stops is a set of integers separated by spaces. A future implementation would put up a graphic that displays the positions at which tabs are set by means of vertical transparent lines at the tops of which would be their numerical values. This display would disappear when any other command was issued. SET TABS creates one or more tabs which are provided by the user in the form of a list of one or more tab stops typed after the command name. Only one- or two-digit numbers are accepted, the second digit changing as further digits are typed. Non-digits are ignored, and a transparent message appears explaining this behavior (and gives the format for tab lists). The message disappears on the next keystroke as usual. Del works as with any text, so that the user can make corrections to typing errors. To use this command, the user first selects the text to which the tabs are to apply, then invokes the command. The more advanced user can select the text to which the tabs are to apply, and then select a list, and then issue the command without a list. The system will take selection 1 as the list and selection 0 as the text to which it is to be applied. If the syntax of the list is incorrect, a transparent error message saying so is given, and no tabs are set. To copy the tab formatting from one portion of a document to another, you would use SHOW TABS to put the list into the text, and then proceed as explained above. CLEAR TABS without a tab list removes all tab stops from the selection. CLEAR TABS with a list clears tabs from the selection at the user-supplied positions. DEFAULT TABS applies the default tab list to the selection. USING THE SELECTION AS A COMMAND Co = DO This command treats the selection as if it were typed while the quasimode was in effect. This permits using a command that appears on the display without having to retype it. If the selection is not a command name, this action results in a transparent error message explaining the problem and how to fix it. The LEAP commands in text are written LEAP> and LEAP< to indicate direction. The remainder of the selection is a LEAP search pattern. This search, unlike the usual standard keyboard LEAP, is case-sensitive. The pattern can include Return, Document, Page, and other special characters. Note that this command has eliminated the need for the "leap forward" and "leap backward" commands that appeared in previous versions. DETERMINING WHAT TASKS ARE EXECUTING Co = TASKS This puts a list of currently operating tasks into the text, selected so that it can be easily deleted. A task is the result of any command such as talking or printing, which takes enough time so that the user has gone on to do other things with THE. The task name is the name of the command that launched it. If the same command has been used again before the first task initiated by that command has completed, then a digit is placed after the name, for example, PRINT2, PRINT3, etc. In later versions the task lists can be made humane by, for example, putting the first few lines of what is printing (or to be printed) alongside or under the items so that the user does not have to remember which was PRINT3. STOP COMMAND Co = STOP If a process is ongoing and is interruptible, then this command should stop the process, prepare to discard any intermediate results, and return the system to the state it had when the previous command was issued. UNDO will restart the process. EMBEDDING PYTHON When a selection that includes both text and Python code is executed (see the run and compile commands) the system has to have a way to distinguish code that is embedded in text. As Python uses indenting as part of its syntax, any line in the selection that begins with two or more spaces is treated as executable (the first line of code must begin with exactly two spaces). This happens only when the run command is invoked on the selection. Any lines that begin with no spaces are treated as comments. Lines with one space will be treated as comments, but it is not recommended that this fact be exploited, as it can make it hard to tell code from comment. This convention has been chosen so that comments can be edited freely, without excessive punctuation (such as three quotes in a row), and yet will word wrap. If you think that this convention makes putting in code more labor-intensive, consider that in a well-documented program there is more (usually much more) comment than code. See Knuth's "Literate Programming" article (reprinted in his book, Literate Programming). For security, it is essential that a program cannot be executed or compiled by an external agent. That is, only the local user can select text that includes code and cause it to be executed or compiled. Certainly, some users can be tricked into allowing trouble-making software to run on their machines, but if there is no way to cause code to be executed remotely, we will have a more secure system. This is, of course, not the only step we need to take in the direction of security. RUN COMMAND Co = RUN A selection can be treated as a program by means of the appropriate command (e.g. runC, runSqueak, or runForth). Eventually, the system may detect the language based on the syntax, and we'd just have a RUN command. This will also work if we have only one programming language. At present, RUN executes Python. Normally, output from a program is inserted at the cursor location, though the programmer can direct it in any way the programming language allows. There is no requirement that Python in particular be the implementation language. It is used as an example here because it is the language of the first implementation and is a reasonably humane language. This specification only requires that any language used in a particular implementation be accessible to users via a RUN command. COMPILING Co = COMPILE This command is used by application and system programmers who wish to modify the humane environment itself, such as by adding commands. This can be done from within the editor. It compiles the main Python source files into bite-compiled Python (.pyc files) and then copies them into the bin folder. For any such changes to take effect you must quit and restart the editor. MAKING CODE MORE VISIBLE Co = BOLDCODE Makes the code portions of a selection bold face without affecting the non-code portions. If some portions of the code are already bold, it will leave them bold. INDENTING AND OUTDENTING BLOCKS OF CODE Co = INDENT n When moving Python code about, it is sometimes necessary to move an entire block of code left or right while leaving ordinary text unaffected. To do this, the INDENT command moves the block to the right by n spaces. If n is negative, the block is moved left. Use of the repeat command (Return) after an INDENT command will visibly move a block of code. SEND COMMAND Co = SEND To send an email, you create and select the text to be sent, then you select the email address (perhaps from your email list, or you might type it). Then you execute the SEND command. If an email address is supplied as part of the command, the selected text is sent to the given email address RECEIVING EMAIL Incoming email should appear at beginning of the incoming email document. It behaves as do the other accumulating documents. Attachments can be brought into the same document. Line feeds immediately before or after returns are ignored, but if not associated with a return are changed into returns. If the system runs out of room while receiving an e-mail or an attachment, a message is made available in the usual manner. OTHER INPUT AND OUTPUT COMMANDS Commands that send a selection to any parallel, serial, USB, Firewire or other port should eventually be provided. Provisions should also be made to receive information from any port. We will discuss implementation. How text is communicated to a foreign system except by email has not been determined. For now, we will probably use plain text, RTF, VML, or HTML (to be discussed). PAGINATION Co = PAGINATE Number all pages in the selection consecutively, resetting to 1 whenever a document character is encountered. Co = PAGINATE You select some text and issue the command, pagination starts at that number. Commands for headers, footers, pagination in Roman numerals, and other page-related material and other pagination schemes will be accommodated by commands. Page numbers will be visible. Ideally, they will be inserted into the text so that they can be LEAPed to, but will still be automatically moved as pagination changes. This feature needs some design attention. SPELLING CHECKING Co = SP For the name of this command, we use the letters that editors use to mark a questionable spelling. This command LEAPs forward to and selects the first word it finds that is not in the environment's word list. If the spelling is as you want it, you can issue the repeat command or the SP command again to find the next word that is not in list (NIL). If you wish to see possible alternatives, you use the NEXT command (which see). PRESENTING ALTERNATIVES Co = NEXT In the case where selection 0 has not been created by the SP or REPLACE commands, the NEXT command first applies the SP command to the selection. If the selection is on the list, a transparent message states that "The selected word is a correct spelling.". If a selection is not a correct spelling (as determined by the SP command applied as above or as invoked by the user), the NEXT command places the most likely alternative (as determined by whatever algorithm we use) in place of selection 0, leaving it selected. It also puts up a transparent message saying "Use the repeat command (Shift Space Return) to see other alternatives." Repeated entry of the NEXT command will also work. When you see the desired alternative, you may resume working (e.g. typing, LEAPing, or another use of the SP command) and the alternative is left in the text. If you have run through all the alternatives, a beep is given, and a transparent message says that all the alternatives have been tried. If you continue to use the repeat command, the list of alternatives will be run through again as often as you wish. You can add the current selection to the dictionary at any time with the ADDWORD command, (which see). ADD A WORD TO THE DICTIONARY Co = ADDWORD (see the spell command for the definition). When a spelling error is detected, and the suggested alternatives displayed, that display should also mention that a word incorrectly pointed to as erroneous can be added to the dictionary with this command, relieving the user of having to remember the command when it is needed. REPLACE AND SEARCH Co = REPLACE You select what you want to use as the replacement string. You then use the "SETREP" command to establish it as the replacement string. You can remove the replacement string from the text by using Delete. The replacement string (or its beginning and ending separated by an ellipsis if it is too long) appears as the usual transparent overlay. You select an instance of the target you wish to replace with the replacement string and use the REPLACE command. This does two things: it replaces the selected text with the replacement string and selects the next instance of the target. If you wish to leave the target unaffected you use the NEXT command. The transparent text goes away when you use any command other than REPLACE, NEXT, or repeat. Rejected alternative definition (and reasons why): When the command is invoked, selection 1 is the "replacement", selection 0 is the "pattern". Then the REPLACE command replaces selection 0 with the replacement and proceeds to select the next instance of the pattern in the text. The repeat command would be used to make the substitution. A LEAP command (not a normal LEAP) is used to leave the instance unchanged and seek the next instance. This is reasonably natural as the pattern for the LEAP is exactly what was selected by the REPLACE command. Note that this LEAP must not change the definition of the replacement, even though the replacement is no longer selection 1. There are problems with this approach, however. It leaves the replacement somewhere in the text -- do we need another command to get rid of it? It is easy to create such a command, but we have put the burden on you to remember to use it after the replacements are done and your locus of attention is not on the replacement. If the software automatically deletes it at the first non-REPLACE, non-LEAP command, it might be deleting something you wanted to keep. Also, it is more natural to have selection 1 be the pattern and selection 0 be the replacement. This is fine except that the focus then has to follow selection 1 after a REPLACE command, whereas at all other times it follows selection 0. On a standard keyboard we cannot present the replacement as an argument, as we have no control over case during a command, yet the replacement might be intended to fix the case of the pattern (e.g. changing every instance of "sourceforge" to "SourceForge".) On a LEAP keyboard, we could use REPLACE firststring WITH secondstring. OLD LEAPS An Old Leaps document contains each pattern that is used to perform a successful LEAP. GRAPHICS When doing graphics, a graphic input device (mouse, tablet, etc.) is essential. The user should not have to switch back to the keyboard in order to issue graphic commands. The following commands, group, stick to page, UNSTICK from page, and stick to screen, facilitate graphics. STICK TO PAGE COMMAND Co = STICKTOPAGE This command allows the user to take a selection and make sure that it does not move with respect to the nearest previous explicit page or document character. A special highlight indicates stuck text. UNSTICK FROM PAGE COMMAND Co = UNSTICKFROMPAGE When unstuck, it becomes inserted at its apparent position in the text. If the selected text is not stuck, this command has no effect. STICK TO SCREEN COMMAND Co = STICKTOSCREEN This command allows the user to take a selection and have it remain in a fixed position on the display (namely, where it was when selected), where it stays on top of all other material on the display. Newer selections cannot be put on top of it because they can't get on top of it. Of course it can be selected and deleted. This may be replaced with a split screen command. LEAVING THE EDITOR Co = QUIT For now, when we are running on various platforms where we are not the primary software (eventually the humane environment is intended be the primary software for its users), this command saves the current state of the system and terminates execution of the humane environment software. Eventually, there should be no QUIT command as there will be nothing to quit to. COLOR CHOICES These colors, chosen by continued experiment and subject to change, are given in RGB color space and in hexadecimal. Selection Colors 0 1 2 3 (and all older) selections R 00 7f bf e1 G ff ff ff ff B cc e6 f3 f9 The 0th old selection color (00 ff cc) is also the color of the non-flashing part of the cursor, which is, after all, the default selection. Indication Color (what will become selected if the select command is invoked; this is the color if we use block indication, use the selection color if we use underline) R fe 254 G f3 243 B a6 166 Cursor Color R ff G 4a B 4a OPEN ISSUES AND DISCUSSIONS OF ALTERNATIVES Specify beep sounds (frequency, duration) and what on the display flashes. Specify flash color alternation and timing. -- Aza How many old selections are retained, and for how long? When does the list of old selections get pruned? -- Jef Add a Sort command as per the Canon Cat. Note that in the Cat, a mistake was made: forward and backward erase were automatic: immediately after a LEAP erase went forward, otherwise it went backwards through the text. Thus LEAP had a side effect of changing erase direction. We have not copied this error. Nonetheless, it worked correctly most of the time. Can we capture the benefit without the problems? TEXTS WITH BOTH LEFT-TO-RIGHT AND RIGHT-TO-LEFT LANGUAGES Let a, b, c be letters in a left-to-right (ltr) language and x, y, z be letters in a right-to-left (rtl) language. As in the other documents, upper case will be used to show the location of the selection and an underlying asterisk the location of the cursor (and, as usual, display this in courier) Consider bCxy * (1) As the cursor is in the ltr portion, deletion would delete the c, leaving Bxy * (2) A further deletion would do what I think most would expect, and delete the b. Ignoring the question of how you type in multiple languages (see footnote below), typing the rtl letter "a" from (2) gives bAxy * (3) Typing the ltr letter "z" from (2) would shift the system into ltr behavior: bZxy * (4) At some future time, the other cases will be examined and a full spec can be produced. For now, it is too low a priority to pursue. Note that with the conventional between-character (PARC) cursor, there is an ambiguity: for example, if you tap Delete, which character will be deleted when the cursor is between a ltr and a rtl pair of characters.